-module(server).

-export([start/0]).

-define(PORT, 5678).
-define(HEAD_SIZE, 4).

-define(UINT, 32/unsigned-big-integer).
-define(INT, 32/signed-big-integer).   
-define(USHORT, 16/unsigned-big-integer).
-define(SHORT, 16/signed-big-integer). 
-define(UBYTE, 8/unsigned-integer).
-define(BYTE, 8/signed-integer). 

start() ->
    {ok, LSock} = gen_tcp:listen(?PORT, [binary,
                      {packet, 0}, {reuseaddr, true}, {active, false}]),
    io:format("start listen port: ~p~n", [?PORT]),
    {ok, Sock} = gen_tcp:accept(LSock),
    gen_tcp:close(LSock),
    recv_head(Sock).

recv_head(Sock) ->
    case gen_tcp:recv(Sock, ?HEAD_SIZE) of 
        {ok, Bin} ->
            io:format("recv head binary = ~p~n", [Bin]),
            <<TotalSize:?UINT>> = Bin,
            BodySize = TotalSize - ?HEAD_SIZE,
            recv_body(Sock, BodySize);
        {error, closed} ->
            io:format("client socket closed.~n")         
    end.    

recv_body(Sock, BodySize) ->
    case gen_tcp:recv(Sock, BodySize) of
        {ok, Bin} ->
            <<CMD:?USHORT, Content/binary>> = Bin,
            io:format("recv body binary = ~p~n", [Bin]),
            io:format("recv protocol CMD = ~p~n", [CMD]),
            io:format("recv protocol content = ~p~n", [Content]),
            ok = gen_tcp:send(Sock, "ok, everything is well!\n"),
            recv_head(Sock);
        {error, closed} ->
            io:format("client socket closed.~n") 
    end.
